package com.wjk.kylin.modules.system.config.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wjk.kylin.core.common.redis.RedisRepository;
import com.wjk.kylin.core.constant.CommonConstant;
import com.wjk.kylin.core.constant.Constants;
import com.wjk.kylin.core.exception.BusinessException;
import com.wjk.kylin.modules.system.config.entity.Config;
import com.wjk.kylin.modules.system.config.mapper.ConfigMapper;
import com.wjk.kylin.modules.system.config.service.IConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

/**
 * <p>
 *  参数配置表 服务实现类
 * </p>
 *
 * @author wangjkui
 * @since 2020-06-07
 */
@Service
@Transactional(readOnly=true)
public class ConfigServiceImpl extends ServiceImpl<ConfigMapper, Config> implements IConfigService {

    @Autowired
    private RedisRepository redisRepository;

    @Override
    public IPage<Config> findPage(Page<Config> page, Config config) {
        return baseMapper.findPage(page,config);
    }

    @Override
    @Transactional(readOnly=false)
    public boolean save(Config config) throws BusinessException{
        //1.判断code是否已经存在
        QueryWrapper<Config> wrapper = new QueryWrapper<>();
        wrapper.eq("code", config.getCode());
        int count = this.count(wrapper);
        if(count > 0){
            throw new BusinessException("参数键名已存在，请重新添加");
        }

        config.preInsert();
        boolean flag = super.save(config);
        //2.加入缓存
//        redisRepository.putHashValue(Constants.CACHE_CONFIG_REDIS_KEY, config.getCode(), config.getValue());

        return flag;
    }

    @Override
    @Transactional(readOnly=false)
    public boolean update(Config config) {
        //1.判断code是否已经存在
        QueryWrapper<Config> wrapper = new QueryWrapper<>();
        wrapper.eq("code", config.getCode());
        wrapper.ne("id",config.getId());
        int count = this.count(wrapper);
        if(count > 0){
            throw new BusinessException("参数键名已存在，请重新修改");
        }

        //2.修改数据库
        config.preUpdate();
        boolean flag = super.updateById(config);
        //1.删除缓存
        redisRepository.delHashValues(Constants.CACHE_CONFIG_REDIS_KEY ,config.getCode());
        //先删除数据库，后删除缓存。为了防止删除缓存之后又查询数据库，然后再次把旧数据添加到缓存
        return flag;
    }

    @Override
    @Transactional(readOnly=false)
    public boolean deleteByIds(String[] configIds) {
        List<String> ids = Arrays.asList(configIds);

        //1查询数据
        List<Config> list = super.listByIds(ids);

        //2.删除数据库
        boolean flag = super.removeByIds(ids);

        //3. 删除缓存
        list.forEach(config ->{
            redisRepository.delHashValues(Constants.CACHE_CONFIG_REDIS_KEY , config.getCode());
        });

        return flag;
    }

    @Override
    public String getConfigKey(String configKey) {

        //1.判断缓存中是否存在
        if(redisRepository.hasHashKey(Constants.CACHE_CONFIG_REDIS_KEY,configKey)){
            return (String) redisRepository.getHashValues(Constants.CACHE_CONFIG_REDIS_KEY,configKey);
        }

        //2.查询数据库
        QueryWrapper<Config> wrapper = new QueryWrapper<>();
        wrapper.eq("code", configKey);
//        wrapper.eq("status", CommonConstant.DataStatus.OK.getCode());//TODO 只有正常才能查询使用
        Config config = this.getOne(wrapper);

        String configValue = ObjectUtil.isNotEmpty(config)?config.getValue():"";

        //3.加入缓存
        redisRepository.putHashValue(Constants.CACHE_CONFIG_REDIS_KEY, configKey, configValue);

        return configValue;
    }

    @Override
    public void clearCache() {
        //清除参数配置的缓存
        redisRepository.del(Constants.CACHE_CONFIG_REDIS_KEY);
    }
}
